/***************************************************************************
 *   mgpi_gpuc.h - Mathematical Calulations using GPU	                   *
 *   Copyright (C) 2008 by cmaster.matso                                   *
 *   cmaster.matso@gmail.com                                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef _GPUC_H
#define _GPUC_H

#ifdef __cplusplus
extern "C" {
#endif

#include "../../main/src/mgpi_stddefs.h"
#include <GL/glsw.h>
#include <GL/glew.h>
#include <GL/glut.h>

    enum MGPI_INPUTS {
        IN0, IN1
    };

#define MGPI_MAX_STREAM_NUM	32
    
#define MGPI_CPU_VECTOR_CALC	10000
#define MGPI_GPU_VECTOR_CALC	10004
#define MGPI_ERR_VECTOR_CALC	11111
#define MGPI_NO_ERROR	0
#define MGPI_KERNEL_NOT_INIT	-1

#define MGPI_GLSL_SHADER    0
#define MGPI_GLSL_PROGRAM   1
    
#define MGPI_GLSL_FLOAT1    10000
#define MGPI_GLSL_FLOAT2    10001
#define MGPI_GLSL_FLOAT3    10002
#define MGPI_GLSL_FLOAT4    10003
#define MGPI_GLSL_FLOATnv   10004
#define MGPI_GLSL_INT1  10005
#define MGPI_GLSL_INT2  10006
#define MGPI_GLSL_INT3  10007
#define MGPI_GLSL_INT4  10009
#define MGPI_GLSL_INTnv 10010
#define MGPI_GLSL_MATRIX2   10011
#define MGPI_GLSL_MATRIX3   10012
#define MGPI_GLSL_MATRIX4   10013
#define MGPI_GLSL_MATRIX2x3 10014
#define MGPI_GLSL_MATRIX3x2 10015
#define MGPI_GLSL_MATRIX2x4 10016
#define MGPI_GLSL_MATRIX4x2 10017
#define MGPI_GLSL_MATRIX3x4 10018
#define MGPI_GLSL_MATRIX4x3 10019
#define MGPI_GLSL_MATRIX2_T   10020
#define MGPI_GLSL_MATRIX3_T   10021
#define MGPI_GLSL_MATRIX4_T   10022
#define MGPI_GLSL_MATRIX2x3_T 10023
#define MGPI_GLSL_MATRIX3x2_T 10024
#define MGPI_GLSL_MATRIX2x4_T 10025
#define MGPI_GLSL_MATRIX4x2_T 10026
#define MGPI_GLSL_MATRIX3x4_T 10027
#define MGPI_GLSL_MATRIX4x3_T 10028

#pragma pack(push,1)

    typedef struct _stream {
        GLuint stream_id;
        int err_flag;
        int n;
        int size;
        int data_type;
        int stream_format;
        int stream_target;
    } GPUstream_t;

    typedef unsigned int gpustrm_t;

    typedef struct _param {
        int action_stream_id;
        int num_streams;
        GPUstream_t *streams;
    } GPUparam_t;

    typedef struct _kernel {
        int usage;
        GLuint glsl_program;
        GLuint fragment_shader;
        GLuint vertex_shader;
    } GPUkernel_t;

    typedef GPUkernel_t shader_t;
    typedef unsigned int gpukrnl_t;

    typedef struct _routine {
        struct _routine *next;
        struct _routine *prev;

        int name;
        GPUparam_t *param;
        void (*setup)(GPUparam_t *);
    } GPUroutine_t;

#pragma pack(pop)

    int MGPI_API MGPI_BeginVectorComputations(int, int *, char **);
    int MGPI_API MGPI_EndVectorComputations(void);

    GPUstream_t MGPI_API *MGPI_AllocGPUStreams(int, int, int, int, int, int);
    GPUparam_t MGPI_API *MGPI_AllocGPUParam(GPUstream_t *, int, int);

    void MGPI_API *MGPI_ReadGPUStream(void *, GPUstream_t *);
    void MGPI_API *MGPI_WriteGPUStreamNV(void *, GPUstream_t *);
    void MGPI_API *MGPI_WriteGPUStreamATI(void *, GPUstream_t *);

    int MGPI_API MGPI_SetGPUVariable(int, const char *, ...);
    int MGPI_API MGPI_SetGPURoutineCode(const char *, const char *);
    int MGPI_API MGPI_SetupGPUParam(GPUparam_t *);
    int MGPI_API MGPI_SetGPURoutineParam(GPUparam_t *);

    int MGPI_API MGPI_RegGPURoutine(GPUparam_t *);
    int MGPI_API MGPI_CallRoutine(int);

    int MGPI_API MGPI_FreeGPUStream(GPUstream_t *);
    int MGPI_API MGPI_FreeGPUParam(GPUparam_t *);
    int MGPI_API MGPI_FreeGPURoutine(int);
    int MGPI_API MGPI_FreeComputKernel(void);

#define MGPI_AllocGPUStreams4NV32(n,s,dt) MGPI_AllocGPUStreams(n,s,dt,GL_RGBA,GL_RGBA32F_ARB,GL_TEXTURE_RECTANGLE_ARB)
#define MGPI_AllocGPUStreamsNV32(n,s,dt) MGPI_AllocGPUStreams(n,s,dt,GL_LUMINANCE,GL_LUMINANCE32F_ARB,GL_TEXTURE_RECTANGLE_ARB)
#define MGPI_AllocGPUStreams4ATI32(n,s,dt) MGPI_AllocGPUStreams(n,s,dt,GL_RGBA,GL_RGBA_FLOAT32_ATI,GL_TEXTURE_RECTANGLE_ARB)
#define MGPI_AllocGPUStreamsATI32(n,s,dt) MGPI_AllocGPUStreams(n,s,dt,GL_LUMINANCE,GL_LUMINANCE_FLOAT32_ATI,GL_TEXTURE_RECTANGLE_ARB)

#define glTangent3f(s,t,r) glMultiTexCoord3f(GL_TEXTURE0+(n-2),s,t,r)
#define glTangent3d(s,t,r) glMultiTexCoord3d(GL_TEXTURE0+(n-2),s,t,r)
#define glTangent4f(s,t,r,q) glMultiTexCoord4f(GL_TEXTURE0+(n-2),s,t,r,q)
#define glTangent4d(s,t,r,q) glMultiTexCoord4d(GL_TEXTURE0+(n-2),s,t,r,q)
#define glTangent3fv(v) glMultiTexCoord3fv(GL_TEXTURE0+(n-2),v)
#define glTangent3dv(v) glMultiTexCoord3dv(GL_TEXTURE0+(n-2),v)
#define glTangent4fv(v) glMultiTexCoord4fv(GL_TEXTURE0+(n-2),v)
#define glTangent4dv(v) glMultiTexCoord4dv(GL_TEXTURE0+(n-2),v)

#define glBinormal3f(s,t,r) glMultiTexCoord3f(GL_TEXTURE0+(n-1),s,t,r)
#define glBinormal3d(s,t,r) glMultiTexCoord3d(GL_TEXTURE0+(n-1),s,t,r)
#define glBinormal4f(s,t,r,q) glMultiTexCoord4f(GL_TEXTURE0+(n-1),s,t,r,q)
#define glBinormal4d(s,t,r,q) glMultiTexCoord4d(GL_TEXTURE0+(n-1),s,t,r,q)
#define glBinormal3fv(v) glMultiTexCoord3fv(GL_TEXTURE0+(n-1),v)
#define glBinormal3dv(v) glMultiTexCoord3dv(GL_TEXTURE0+(n-1),v)
#define glBinormal4fv(v) glMultiTexCoord4fv(GL_TEXTURE0+(n-1),v)
#define glBinormal4dv(v) glMultiTexCoord4dv(GL_TEXTURE0+(n-1),v)

#ifdef __cplusplus
}
#endif

#endif
